package com.xyy.saas.payment.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xyy.saas.payment.adpater.impl.XydLoanAdapter;
import com.xyy.saas.payment.adpater.xydLoan.core.dto.XydNotifyCancelRepaymentDto;
import com.xyy.saas.payment.adpater.xydLoan.core.req.*;
import com.xyy.saas.payment.adpater.xydLoan.core.resp.XydAuthCreditResp;
import com.xyy.saas.payment.adpater.xydLoan.core.resp.XydMerchantInfoSyncResp;
import com.xyy.saas.payment.adpater.xydLoan.service.XydLoanService;
import com.xyy.saas.payment.callback.core.result.CallbackRunner;
import com.xyy.saas.payment.common.RocketMqTag;
import com.xyy.saas.payment.common.RocketMqTopic;
import com.xyy.saas.payment.common.exception.PaymentException;
import com.xyy.saas.payment.cores.enums.ChannelEnum;
import com.xyy.saas.payment.cores.enums.ResultCodeEnum;
import com.xyy.saas.payment.cores.param.XYDPushLoanSceneDto;
import com.xyy.saas.payment.cores.vo.ResultVO;
import com.xyy.saas.payment.dao.model.PayResultOrder;
import com.xyy.saas.payment.merchant.core.dto.QueryTradeCertificateDto;
import com.xyy.saas.payment.merchant.core.dto.RechargeHandleDto;
import com.xyy.saas.payment.merchant.core.dto.TradeCertificateVo;
import com.xyy.saas.payment.merchant.core.service.SeparateOrderService2;
import com.xyy.saas.payment.payment.core.service.ProfitSharingService;
import com.xyy.saas.payment.payment.core.service.XydCreditLoanService;
import com.xyy.saas.payment.service.PayResultOrderService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;

/**
 * @author wangzeqi
 */
@Slf4j
@RestController
@RequestMapping(value = {"/api/xydLoan/test"})
public class XydLoanTestController {

    @Autowired
    private XydLoanService xydLoanService;

    @Autowired
    private XydCreditLoanService xydCreditLoanService;

    @Autowired
    private XydLoanAdapter xydLoanAdapter;
    @Autowired
    private ProfitSharingService profitSharingService;
    @Autowired
    private SeparateOrderService2 separateOrderService2;
    @Autowired
    private PayResultOrderService payResultOrderService;
    @Autowired
    private CallbackRunner callbackRunner;

    /**
     * 查询交易回单
     */
    @PostMapping("/queryTradeCertificate")
    public ResultVO<TradeCertificateVo> queryTradeCertificate(@RequestBody QueryTradeCertificateDto dto) {
        try {
            log.info("###查询交易回单 dto:{}", JSON.toJSONString(dto));
            TradeCertificateVo tradeCertificateVo = separateOrderService2.queryTradeCertificate(dto);
            return ResultVO.createSuccess(tradeCertificateVo);
        } catch (Exception e) {
            log.error("###查询交易回单 error, dto:{}", JSON.toJSONString(dto), e);
            return ResultVO.createError(e.getMessage());
        }
    }

    /**
     * 支付结算补偿
     */
    @PostMapping("/xydCreditPaySettle")
    public String xydCreditPaySettle(String payNo) {
        if (StringUtils.isBlank(payNo)) {
            return "param error";
        }

        try {
            profitSharingService.xydCreditPaySettle(payNo);
        } catch (Exception e) {
            log.error("xydCreditPaySettle error, {}-{}", payNo, e.getMessage(), e);
            return "error";
        }
        return "success";
    }

    @PostMapping("/xydCreditPaySettleSendMq")
    public String xydCreditPaySettleSendMq(String payNo) {
        log.info("xydCreditPaySettleSendMq {}", payNo);

        if (StringUtils.isBlank(payNo)) {
            return "param error";
        }

        try {
            PayResultOrder payResultOrder = payResultOrderService.selectByPayNoAndChannel(payNo, ChannelEnum.XYD_LOAN.getCode());
            if (payResultOrder == null) {
                log.error("xydCreditPaySettleSendMq {} order_not_exist", payNo);
                throw new PaymentException(ResultCodeEnum.ORDER_NOT_EXIST);
            }

            RechargeHandleDto rechargeHandleDto = RechargeHandleDto.builder().
                    rechargeType(RechargeHandleDto.PAY).
                    channel(payResultOrder.getPayChannel()).
                    orderNo(payResultOrder.getPayNo()).
                    accountId(payResultOrder.getReceiveId()).
                    build();
            callbackRunner.syncSendMsgWithTag(RocketMqTopic.TOPIC_RECHARGE_HANDLE, RocketMqTag.TOPIC_RECHARGE_HANDLE_XYD_CREDIT_PAY_SETTLE_TAG, rechargeHandleDto);

        } catch (Exception e) {
            log.error("xydCreditPaySettleSendMq error, {}-{}", payNo, e.getMessage(), e);
            return "error";
        }

        return "success";
    }

    /**
     * 退款结算补偿
     */
    @PostMapping("/xydCreditRefundSettle")
    public String xydCreditRefundSettle(String refundNo) {
        if (StringUtils.isBlank(refundNo)) {
            return "param error";
        }

        try {
            profitSharingService.xydCreditRefundSettle(refundNo);
        } catch (Exception e) {
            log.error("xydCreditPaySettle error, {}-{}", refundNo, e.getMessage(), e);
            return "error";
        }
        return "success";
    }

    @PostMapping("/authCredit")
    public String authCredit() {
        try {
            XydAuthCreditResp resp = xydLoanService.authCredit(XydAuthCreditReq.mock());
            System.out.println(JSONObject.toJSON(resp));
            return "h5Url";
        } catch (Exception e) {
            log.error("authCredit error", e);
            return "error";
        }
    }

    @PostMapping("/loanDataSync")
    public boolean loanDataSync() {
        try {
            return xydLoanService.loanDataSync(XydLoanDataSyncReq.mock());
        } catch (Exception e) {
            log.error("authCredit error", e);
            return false;
        }
    }

    @PostMapping("/merchantInfo/sync")
    public void merchantInfoSync(@RequestBody String merchantId) {
        XydMerchantInfoSyncResp xydMerchantInfoSyncResp = xydCreditLoanService.merchantInfoSync(XydMerchantInfoSyncReq.mock(merchantId));
        System.out.println("==");
    }

    @PostMapping("/historyOrderInfo/sync")
    public void historyOrderInfoSync(@RequestBody String merchantId) {
        System.out.println("==");
        xydCreditLoanService.historyOrderInfoSync(XydHistoryOrderInfoSyncReq.mock(merchantId));
    }

    /**
     * 通知放款结果
     */
    @PostMapping("/notify/loan-result")
    public void notifyLoanResult(@RequestBody XydNotifyLoanResultReq param) {
        log.info("通知放款结果 自测 小雨点callback：{}", JSONObject.toJSONString(param));
       xydCreditLoanService.notifyLoanResult(param);
    }
    /**
     * 通知放款结果-新增借据记录
     */
    @PostMapping("/notify/addRepayPlan")
    public ResultVO addRepayPlanResult(@RequestBody XydNotifyLoanResultReq param) {
        log.info("新增借据记录 自测 小雨点callback：{}", JSONObject.toJSONString(param));
        xydCreditLoanService.addRepayPlanResult(param);
        return ResultVO.createSuccess();
    }
    /**
     * 4.2.2.1通知还款结果
     */
    @PostMapping("/notify/repaymentResults")
    public void notifyRepaymentResults(@RequestBody String param) {
        log.info("通知还款结果-自测-小雨点callback：{}",JSONObject.toJSONString(param));
        xydCreditLoanService.notifyRepaymentResults(JSON.parseObject(param, XydNotifyRepaymentResultsReq.class));
    }

    /**
     * 小雨点存量数据 还款计划初始化
     * @param payNoList
     */
    @PostMapping("/initRepayPlan")
    public void initRepayPlan(@RequestBody List<String> payNoList) {
        xydCreditLoanService.initRepayPlan(payNoList);
    }

    /**
     * 7.2查询放款结果
     */
    @PostMapping("/queryPayResults")
    public Object queryPayResults(@RequestBody XydSearchLoanResultReq param) {
        log.info("查询放款结果：{}",JSONObject.toJSONString(param));
        try {
            return xydLoanService.searchLoanResult(param);
        } catch (PaymentException e) {
            log.error("查询放款结果 {}",JSONObject.toJSONString(param),e);
        }
        return null;
    }
    /**
     * 7.1查询授信结果
     */
    @PostMapping("/searchCreditResult")
    public Object searchCreditResult(String thirdUserNo, String businessLicense) {
        log.info("查询授信结果searchCreditResult：thirdUserNo:{},businessLicense:{}",thirdUserNo,businessLicense);
        try {
            return xydLoanService.searchCreditResult(thirdUserNo,businessLicense);
        } catch (PaymentException e) {
            log.error("查询授信结果 {}",thirdUserNo,e);
        }
        return null;
    }

    /**
     * 取消放款
     */
    @PostMapping("/cancelPay")
    public void cancelPay(@RequestBody XydLoanCancelReq param) {
        log.info("取消放款:{}",JSONObject.toJSONString(param));
        try {
            xydLoanService.loanCancel(param);
        } catch (PaymentException e) {
            log.error("取消放款 {}",param,e);
        }
    }

    /**
     * 通知取消还款
     */
    @PostMapping("/notify/cancelRepayment")
    public void cancelRepayment(@RequestBody XydNotifyCancelRepaymentDto repaymentDto) {
        try {
            xydCreditLoanService.cancelRepayment(repaymentDto);
        } catch (Exception e) {
            log.error("通知取消还款 param:{}", JSONObject.toJSONString(repaymentDto));
        }
    }

    /**
     * 5贷中数据推送
     */
    @PostMapping("/pushLoanSceneData")
    public void pushLoanSceneData() {
        XYDPushLoanSceneDto param = new XYDPushLoanSceneDto();
        param.setMerchantId(123123123L);
        param.setOrderList(getXydOrderInfo(123123123L));
        param.setLogisticsList(getXydLogisticsInfo());
        log.info("小雨点 5贷中数据推送:{}",JSONObject.toJSONString(param));
        try {
            xydLoanAdapter.pushLoanSceneData(param);
        } catch (Exception e) {
            log.error("小雨点 5贷中数据推送 {}",param,e);
        }
    }

    /**
     * 12 获取记账文件
     */
    @GetMapping("/getFile")
    public Object getFile(@RequestParam("fileType") String fileType,
                          @RequestParam("checkDate") String checkDate,
                          @RequestParam("checkCycle") String checkCycle) {
        XydGetFileReq fileReq = new XydGetFileReq();
        fileReq.setFileType(fileType);
        fileReq.setCheckCycle(checkCycle);
        fileReq.setCheckDate(checkDate);
        try {
            return xydLoanService.getFile(fileReq);
        } catch (PaymentException e) {
            log.error("getFile error:{}", e.getMessage(), e);
        }
        return "error";
    }

    /**
     * 13 查询账户余额
     */
    @GetMapping("/queryAccountBalance")
    public Object queryAccountBalance(@RequestParam("accountNo") String accountNo) {
        XydAccountBalanceReq balanceReq = new XydAccountBalanceReq();
        balanceReq.setAccountNo(accountNo);
        try {
            return xydLoanService.queryAccountBalance(balanceReq);
        } catch (PaymentException e) {
            log.error("queryAccountBalance error:{}", e.getMessage(), e);
        }
        return "error";
    }

    private List<XYDPushLoanSceneDto.XydLogisticsData> getXydLogisticsInfo() {
        XYDPushLoanSceneDto.XydLogisticsData xydLogisticsData = new XYDPushLoanSceneDto.XydLogisticsData();
        xydLogisticsData.setReceivingAddress("北京市酒仙桥798");

        //TODO 配送方式待确认
        xydLogisticsData.setDeliveryType("1");
        xydLogisticsData.setMerchantName("买家名称");
        xydLogisticsData.setMobile("13999999999");
        xydLogisticsData.setLogisticsCompanyName("物流公司名字");
        xydLogisticsData.setTargetOrderId("12354234534645756");
        xydLogisticsData.setWaybillNo("sf234234234");
        xydLogisticsData.setCurrentLogisticsState("0");

        //物流状态日期
        xydLogisticsData.setUpdateTime("2025-03-02 12:12:12");

        xydLogisticsData.setOrgName("卖家名称");
        return Collections.singletonList(xydLogisticsData);
    }

    private List<XYDPushLoanSceneDto.XydOrderInfo> getXydOrderInfo(long l) {
        XYDPushLoanSceneDto.XydOrderInfo xydOrderInfo = new XYDPushLoanSceneDto.XydOrderInfo();
        xydOrderInfo.setOrderCreateMth("2025-03");
        xydOrderInfo.setPaidCnt(100);
        xydOrderInfo.setPaidAmount(new BigDecimal("123333.98"));
        xydOrderInfo.setRefundCnt(20);
        xydOrderInfo.setRefundAmount(new BigDecimal("50.01"));
        return Collections.singletonList(xydOrderInfo);
    }
}
